
BULLET_STATE        = 0
BULLET_X            = 1
BULLET_Y            = 3
BULLET_SPEEDX       = 5
BULLET_SPEEDY       = 6
BULLET_SCREENX      = 7
BULLET_SCREENY      = 8
BULLET_OLDCHAR      = 9
BULLET_DATA_SIZE    = 10

bullet_data

    BYTE    1
    WORD    1600, 1600
    BYTE    16, 0
    BYTE    2, 4
    BYTE    0
    
NUM_BULLETS         = 1    


updatebullets

        ; Set vector A to point the first bullet data

        lda #<bullet_data
        sta PGZERO_VECTOR_A
        
        lda #>bullet_data
        sta PGZERO_VECTOR_A+1

        ldx #NUM_BULLETS
        
ub_loop
    
        jsr updatebullet
        
        ; Increase pg zero vector to next bullet
        lda PGZERO_VECTOR_A
        clc
        adc #BULLET_DATA_SIZE
        sta PGZERO_VECTOR_A
        lda PGZERO_VECTOR_A+1        
        adc #0
        sta PGZERO_VECTOR_A+1
        
        
        dex                 ; Decrease counter        
        bne ub_loop         ; If we reached 0, stop iterating
        
        rts
        
;============================================================        
        
updatebullet

        txa
        pha
        
        ; Check state of the bullet and skip update if it's disabled 
        
        ldy #BULLET_STATE
        lda (PGZERO_VECTOR_A),y
        bne ub_bulletactive
        
        jmp ub_end
        
ub_bulletactive        
                
        jsr bulletsetbvectortoscreen
        
        ; Restore the old character
        ldy #BULLET_OLDCHAR
        lda (PGZERO_VECTOR_A),y                           
        ldy #0                                
        sta (PGZERO_VECTOR_B),y
        
        ; Update logic coords
        
        jsr bulletupdatelogicpos
                        
        ; Calc new screenx & screeny
        
        jsr bulletcalcscreenpos
        
        ; Set vector B to the new screen pointer
        
        jsr bulletsetbvectortoscreen
        
        ; Save old char
        
        ldy #0
        lda (PGZERO_VECTOR_B),y
        ldy #BULLET_OLDCHAR
        sta (PGZERO_VECTOR_A),y
        
        ; Draw bullet char
        
        ldy #0
        lda #0
        sta (PGZERO_VECTOR_B),y
                 
ub_end
        
        pla
        tax

        rts
        
;============================================================================        
        
bulletsetbvectortoscreen

        lda dtm_screen_adress
        sta PGZERO_VECTOR_B
        lda dtm_screen_adress+1        
        sta PGZERO_VECTOR_B+1
        
        ; Load the bullet's screeny coord
        ldy #BULLET_SCREENY
        lda (PGZERO_VECTOR_A),y
        
        ; Store screeny into multiplyby40 param                
        sta mb40_param
        lda #0
        sta mb40_param+1
        
        ; Multiply screeny by 40
        jsr multiplyby40
        
        ; Add bullet's screenx coord
        ldy #BULLET_SCREENX
        lda mb40_param
        clc
        adc (PGZERO_VECTOR_A),y
        sta mb40_param
        lda mb40_param+1
        adc #0
        sta mb40_param+1        
        
        ; Now mb40_param == screeny * 40 + screenx
        ; Add mb40_param (screen buffer offset) to screen base pointer
        
        lda PGZERO_VECTOR_B
        clc
        adc mb40_param
        sta PGZERO_VECTOR_B
        lda PGZERO_VECTOR_B+1        
        adc mb40_param+1
        sta PGZERO_VECTOR_B+1

        rts
        
;==================================================

bulletupdatelogicpos

        ; Add speedx to x
        ldy #BULLET_X
        lda (PGZERO_VECTOR_A),y
        ldy #BULLET_SPEEDX
        clc
        adc (PGZERO_VECTOR_A),y
        ldy #BULLET_X
        sta (PGZERO_VECTOR_A),y
        iny
        lda (PGZERO_VECTOR_A),y
        adc #0
        sta (PGZERO_VECTOR_A),y
        
        ; Add speedy to y
        ldy #BULLET_Y
        lda (PGZERO_VECTOR_A),y
        ldy #BULLET_SPEEDY
        clc
        adc (PGZERO_VECTOR_A),y
        ldy #BULLET_Y
        sta (PGZERO_VECTOR_A),y
        iny
        lda (PGZERO_VECTOR_A),y
        adc #0
        sta (PGZERO_VECTOR_A),y   
        
        rts     
        
;====================================================

bcsp_aux_x  word    0
bcsp_aux_y  word    0

bulletcalcscreenpos

        ; Load x into aux variable
        ldy #BULLET_X
        lda (PGZERO_VECTOR_A),y
        sta bcsp_aux_x
        iny
        lda (PGZERO_VECTOR_A),y
        sta bcsp_aux_x+1
        
        ; Substract 32 to x
        lda bcsp_aux_x
        sec
        sbc #32
        sta bcsp_aux_x
        lda bcsp_aux_x+1        
        sbc #0
        sta bcsp_aux_x+1
        
        ; Divide x by 16 (do 4 right shifts)
        lda bcsp_aux_x+1
        lsr
        sta bcsp_aux_x+1
        lda bcsp_aux_x
        ror
        sta bcsp_aux_x
                
        lda bcsp_aux_x+1
        lsr
        sta bcsp_aux_x+1
        lda bcsp_aux_x
        ror
        sta bcsp_aux_x
        
        lda bcsp_aux_x+1
        lsr
        sta bcsp_aux_x+1
        lda bcsp_aux_x
        ror
        sta bcsp_aux_x
        
        lda bcsp_aux_x+1
        lsr
        sta bcsp_aux_x+1
        lda bcsp_aux_x
        ror
        sta bcsp_aux_x
        
        ; Store x into screenx
        lda bcsp_aux_x
        ldy #BULLET_SCREENX
        sta (PGZERO_VECTOR_A),y
                       
        ; Load y into aux variable
        ldy #BULLET_Y
        lda (PGZERO_VECTOR_A),y
        sta bcsp_aux_y
        iny
        lda (PGZERO_VECTOR_A),y
        sta bcsp_aux_y+1
        
        ; Substract 50 to y
        lda bcsp_aux_y
        sec
        sbc #50
        sta bcsp_aux_y
        lda bcsp_aux_y+1        
        sbc #0
        sta bcsp_aux_y+1
        
        ; Divide y by 16 (do 4 right shifts)
        lda bcsp_aux_y+1
        lsr
        sta bcsp_aux_y+1
        lda bcsp_aux_y
        ror
        sta bcsp_aux_y
                
        lda bcsp_aux_y+1
        lsr
        sta bcsp_aux_y+1
        lda bcsp_aux_y
        ror
        sta bcsp_aux_y
        
        lda bcsp_aux_y+1
        lsr
        sta bcsp_aux_y+1
        lda bcsp_aux_y
        ror
        sta bcsp_aux_y
        
        lda bcsp_aux_y+1
        lsr
        sta bcsp_aux_y+1
        lda bcsp_aux_y
        ror
        sta bcsp_aux_y
        
        ; Store y into screeny
        lda bcsp_aux_y
        ldy #BULLET_SCREENY
        sta (PGZERO_VECTOR_A),y

        rts        
        
;==================================================               
; multiplyby40 :  mb40_param = (mb40_param << 5) + (mb40_param << 3)

mb40_param  word    0        
mb40_aux32  word    0        
mb40_aux8   word    0        
        
multiplyby40

        ; Copy param to aux32 & aux8
        
        lda mb40_param
        sta mb40_aux32
        sta mb40_aux8
        
        lda mb40_param+1
        sta mb40_aux32+1
        sta mb40_aux8+1
        
        ; Multiply aux32 by 32
        
        lda mb40_aux32
        asl
        sta mb40_aux32
        lda mb40_aux32+1
        rol
        sta mb40_aux32+1
        
        lda mb40_aux32
        asl
        sta mb40_aux32
        lda mb40_aux32+1
        rol
        sta mb40_aux32+1
        
        lda mb40_aux32
        asl
        sta mb40_aux32
        lda mb40_aux32+1
        rol
        sta mb40_aux32+1
        
        lda mb40_aux32
        asl
        sta mb40_aux32
        lda mb40_aux32+1
        rol
        sta mb40_aux32+1
        
        lda mb40_aux32
        asl
        sta mb40_aux32
        lda mb40_aux32+1
        rol
        sta mb40_aux32+1
        
                
        ; Multiply aux8 by 8
        
        lda mb40_aux8
        asl
        sta mb40_aux8
        lda mb40_aux8+1
        rol
        sta mb40_aux8+1
        
        lda mb40_aux8
        asl
        sta mb40_aux8
        lda mb40_aux8+1
        rol
        sta mb40_aux8+1
        
        lda mb40_aux8
        asl
        sta mb40_aux8
        lda mb40_aux8+1
        rol
        sta mb40_aux8+1
        
        ; Add both and copy to mb40_param
        
        lda mb40_aux32
        clc
        adc mb40_aux8
        sta mb40_param
        
        lda mb40_aux32+1        
        adc mb40_aux8+1
        sta mb40_param+1
                
        rts        